-- card: 16890 from stack: in.3 -- bmap block id: 17455 -- flags: 4000 -- background id: 16896 -- name: Replace ----- HyperTalk script ----- on opencard hide card field "source" put empty into card field "new" pass opencard end opencard on Install put ChooseTargetStack() into it InstallResource XFCN,Replace,it end Install -- part 2 (field) -- low flags: 01 -- high flags: 0007 -- rect: left=305 top=58 right=170 bottom=478 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 3 -- text size: 9 -- style flags: 0 -- line height: 12 -- part name: old -- part 3 (button) -- low flags: 00 -- high flags: 8004 -- rect: left=50 top=308 right=324 bottom=225 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: Replace Case Sensitive ----- HyperTalk script ----- on mouseUp put empty into card field "new" put Replace(card field "old","mytest","myTest",true) into card field "new" set the cursor to hand end mouseUp -- part 6 (button) -- low flags: 00 -- high flags: 8003 -- rect: left=304 top=299 right=321 bottom=425 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: Show C Source ----- HyperTalk script ----- on mouseUp get the visible of card field "source" set the visible of card field "source" to not it if it is false then set the name of me to "Hide C Source" else set the name of me to "Show C Source" end if end mouseUp -- part 8 (field) -- low flags: 01 -- high flags: 0007 -- rect: left=305 top=181 right=292 bottom=478 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 3 -- text size: 9 -- style flags: 0 -- line height: 12 -- part name: new -- part 9 (field) -- low flags: 01 -- high flags: 2007 -- rect: left=18 top=33 right=288 bottom=290 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 3 -- text size: 10 -- style flags: 0 -- line height: 13 -- part name: Documentation -- part 7 (field) -- low flags: 81 -- high flags: 0007 -- rect: left=18 top=31 right=290 bottom=489 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 3 -- text size: 10 -- style flags: 0 -- line height: 13 -- part name: Source -- part 10 (button) -- low flags: 00 -- high flags: 8004 -- rect: left=50 top=292 right=308 bottom=225 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: Replace Case Insensitive ----- HyperTalk script ----- on mouseUp put empty into card field "new" put Replace(card field "old","mytest","myTest",false) into card field "new" set the cursor to hand end mouseUp -- part contents for card part 2 ----- text ----- on test global myTest put mytest + 1 into MYTest if MYTEST > 100 then beep put 0 into MyTest end if end test -- part contents for card part 7 ----- text ----- /* Replace1.2d1.c */ /* © Trustees of Dartmouth College */ /* written in LightSpeed C © Think Technologies, Inc */ /* by Roger Brown 7/21/88 Courseware Development Group */ /* version 1.2d1 3/30/90 compiles under Think C 4.0 and fixes the bug of replacing something with a null string. /* version 1.2d0 is invisible replace only, using off-screen TextEdit */ /* This uses TextEdit to do the editing, which is not the most efficient method, but it is a precursor to a later version that will display the text as it is edited and allow user verification. */ /* This is a HyperCard XFCN that locates a target string in an input container, replaces the string with another string and returns the edited result. Case sensitivity is an optional third parameter. Syntax is: get Replace(container,oldString,newString,caseSensitive) ex. put Replace(card field 1,"myGlobal","myOtherGlobal",false) into card field 1 returns: a copy of the input container with all occurrences of newString replaced by oldString. where container is any hypercard container (field, variable), presumed to be multi-lined. oldString is the string to look for newString is the string to replace oldString with caseSensitive is an optional parameter turning on case sensitivity To compile: create a project with this, ANSI-A$ library. and MacTraps. Build as code resource type XFCN named Replace. */ #include "ToolboxUtil.h" #include "QuickDraw.h" #include "TextEdit.h" #include "HyperXCmd.h" #include "XCmdGlue.inc.c" #include "SetUpA4.h" #define FALSE 0 #define TRUE !FALSE #define MAXINT 32768 /* globals */ Handle theContainer; /* hanle to the original container */ char *oldString; /* pointer to the string to replace */ char *newString; /* pointer to the string to replace with */ Boolean caseSensitive; /* flag - case sensitive match */ Handle resultH; /* handle to the edited data */ XCmdBlockPtr gParamPtr; TEHandle theTEH; /* change a string to all upper case */ ucase(s) char *s; { int i; char c; for (i=0;i= start) { /* don't go until something matches */ while (matchChar(*tc,*fc,caseSens)) { /* check for match */ fc++; /* cycle through matching characters */ tc++; if (tc == (theTarget+tLen)){ /* all target characters matched */ return c; /* matched */ } } } c++; /* move along */ lPos++; fc = theField + c; /* reset pointer after a search */ } return -1; /* target not found */ } /* replace all occurences of the text without showing the user */ ReplaceInvisible() { Rect aRect; int selStart,selEnd; int oPos,nLen,oLen; GrafPtr curPort,tempPort; /* we are going to use TextEdit to do this and TextEdit wants to be in a port so we are going to save the current port, create a new one and move it off screen, do the replacing, and restore the original port. */ GetPort(&curPort); /* save to restore later */ /* open an offscreen graph port */ tempPort = (GrafPtr)NewPtr(sizeof(GrafPort)); OpenPort(tempPort); MovePortTo(-MAXINT,-MAXINT); /* create a TextEdit record */ SetRect(&aRect,-MAXINT,-MAXINT,-MAXINT+200,-MAXINT+200); theTEH = TENew(&aRect,&aRect); (**theTEH).inPort = tempPort; oLen = strlen(oldString); nLen = strlen(newString); /* initialize the TERecord with the container text */ TESetText(*theContainer,(long)strlen(*theContainer),theTEH); /* do the replacing */ oPos = 0; selStart = FindIt(*(**theTEH).hText,(**theTEH).teLength,oldString,caseSensitive,oPos); while (selStart != -1) { selEnd = selStart + oLen; TESetSelect(selStart,selEnd,theTEH); TECut(theTEH); if (nLen > 0)/* trap here for null replacement string */ TEInsert(newString,(long)nLen,theTEH); oPos = (**theTEH).selEnd; selStart = FindIt(*(**theTEH).hText,(**theTEH).teLength,oldString,caseSensitive,oPos); } /* return the edited text as the result */ resultH = NewHandle((**theTEH).teLength+1); BlockMove((*(**theTEH).hText),*resultH,(**theTEH).teLength); *(*resultH+(**theTEH).teLength) = 0; /* dispose the port and restore the original */ ClosePort(tempPort); SetPort(curPort); DisposPtr(tempPort); } /* XCMD entry */ pascal void Replace(paramPtr) XCmdBlockPtr paramPtr; { int i; Str255 paramStr; Ptr casePtr,verPtr; CursHandle theCursor; gParamPtr = paramPtr; /* put up a watch */ theCursor = GetCursor(watchCursor); SetCursor(*theCursor); /* lock parameters down so we can point to themn */ for (i=0;iparamCount;i++) { MoveHHi(paramPtr->params[i]); HLock(paramPtr->params[i]); } /* get the parameters */ theContainer = paramPtr->params[0]; /* the container */ oldString = *(paramPtr->params[1]); /* the target string */ newString = *(paramPtr->params[2]); /* the replace string */ if (paramPtr->paramCount>3) { /* case sensitivity flag */ casePtr = *(paramPtr->params[3]); strcpy(paramStr,casePtr); } else strcpy(paramStr,""); ucase(paramStr); if (strcmp(paramStr,"TRUE")==0) caseSensitive = TRUE; else caseSensitive = FALSE; ReplaceInvisible(); /* assemble the return string */ paramPtr->returnValue = resultH; for (i=0;iparamCount;i++) HUnlock (paramPtr->params[i]); return; } pascal void main(paramPtr) XCmdBlockPtr paramPtr; /* this is the entry point for the XFCN */ { RememberA0(); SetUpA4(); /* to access globals */ Replace(paramPtr); RestoreA4(); return; } -- part contents for card part 9 ----- text ----- Replace version 1.2d1.c Roger Brown Replace is an XFCN that replaces all occurrences of specified target text with new text in a HyperCard container. The input is a container, the old text, the new text, and a case sensitivity flag. The output is an edited copy of the container data. This version does not support wildcards or pattern matching, and does not allow the user to verify each replacement. We plan to add these features in a later version, so the source for this utilizes toolbox TextEdit to do the replacement in an off-screen port. This is not the most efficient method for this particular XFCN, but it serves as a precursor to later development. The operation is still fairly fast. This XFCN is best used as part of scripts that identify the containers (scripts, fields, globals) to be edited. For example, the SearchScript utility shipped with HyperCard could be modified to be a ReplaceScript utility by replacing "edit the script of" with this XFCN. INVOKING Replace get Replace(container,oldText,newText, caseSens) where container is any HyperCard container oldText is the text to be replaced newText is the text to replace with caseSens is an option flag indicating if the replacement will be case sensitive EXAMPLE ex. put Replace(the script of this card," myglobal","MyGlobal",false) into the script of this card) This example will correct the upper case appearance of all references to MyGlobal. REVISION HISTORY 1.2d0.c First public release. Non-verify version. 1.2d1 3/30/90 Fixed hang when replacing any text with a null string. Compiled with Think C version 4.0. -- part contents for card part 8 ----- text ----- on test global myTest put myTest + 1 into myTest if myTest > 100 then beep put 0 into myTest end if end test